using System;
using System.Collections.Generic;
using System.ComponentModel;
using FPLibrary;
using UnityEngine;

namespace PathX
{
    /// <summary>
    /// Data class for encapsulating and storing grid data.
    /// </summary>
    public class CellMatrixData : ScriptableObject
    {
        [SerializeField,HideInInspector]
        private FPVector _origin;
        [SerializeField,HideInInspector]
        private FPVector _start;
        [SerializeField,HideInInspector]
        private FPBB _bounds;
        [SerializeField,HideInInspector]
        private Fix64 _cellSize;
        [SerializeField,HideInInspector]
        private int[] _blockedIndexes;

        /// <summary>
        /// Creates a data instance from the specified configuration.
        /// </summary>
        /// <param name="matrix">The matrix to store.</param>
        /// <returns>The data instance</returns>
        public static CellMatrixData Create(CellMatrix matrix)
        {
            var data = ScriptableObject.CreateInstance<CellMatrixData>();

            data.Initialize(matrix);

            return data;
        }

        /// <summary>
        /// Updates the data with the new state of the matrix.
        /// </summary>
        /// <param name="matrix">The matrix.</param>
        public void Refresh(CellMatrix matrix)
        {
            Initialize(matrix);
        }

        internal DataAccessor GetAccessor()
        {
            return new DataAccessor(this);
        }

        private void Initialize(CellMatrix cellMatrix)
        {
            var sizeX = cellMatrix.columns;
            var sizeZ = cellMatrix.rows;

            var matrix = cellMatrix.rawMatrix;

            var blockedIndexsList = new List<int>();
            for (int x = 0; x < sizeX; x++)
            {
                for (int z = 0; z < sizeZ; z++)
                {
                    var arrIdx = (z * sizeX) + x;

                    var cell = matrix[x, z];
                    if(cell.IsWalkable(AttributeMask.All))
                    {
                        blockedIndexsList.Add(arrIdx);
                    }
                }
            }

            _blockedIndexes = blockedIndexsList.ToArray();
        }

        internal class DataAccessor
        {
            private CellMatrixData _data;
            private HashSet<int> _blockedLookup;

            internal DataAccessor(CellMatrixData data)
            {
                _data = data;
                _blockedLookup = new HashSet<int>(_data._blockedIndexes);
            }

            internal bool IsPermaBlocked(int idx)
            {
                return _blockedLookup.Contains(idx);
            }
        }

        public static CellMatrix ToMatrix(CellMatrixData data)
        {
            return null;
            // return CellMatrix.Create();
        }
    }

    public class MapBakedData : ScriptableObject
    {
        
        

        public static MapBakedData CurrentMapData
        {
            get;
            private set;
        }
        public static void SetCurrentMap(MapBakedData data)
        {
            CurrentMapData = data;
        }
    }
}